package com.hk.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hk.context.BaseContext;
import com.hk.core.basePageResult.BasePageResult;
import com.hk.domain.*;
import com.hk.dto.ContractChangeDto;
import com.hk.dto.ContractDto;
import com.hk.mapper.*;
import com.hk.service.ContractService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.UUID;

@Service
public class ContractServiceImpl extends ServiceImpl<ContractMapper, Contract> implements ContractService {

    @Autowired
    private ContractMapper contractMapper;
    @Autowired
    private ActivityMapper activityMapper;
    @Autowired
    private CourseMapper  courseMapper;
    @Autowired
    private BusinessMapper businessMapper;
    @Autowired
    private RedisTemplate<String,String> redisTemplate;
    @Autowired
    private UserMapper userMapper;


    /** 优惠类型 ： 打折 */
    public static final String DISCOUNT_TYPE_DISCOUNT = "1";
    /** 优惠类型 ： 代金券 */
    public static final String DISCOUNT_TYPE_VOUCHERS = "0";
    /** 保留位数 */
    private static final int RETENTION_NUMBER = 2;
    /** 除数 */
    private static final int DIVISOR = 10;

    @Override
    public BasePageResult getList(ContractDto contractDto) {
        Page<Contract> contractPage = new Page<>(contractDto.getPageNum(), contractDto.getPageSize());
        LambdaQueryWrapper<Contract> wrapper = new LambdaQueryWrapper<Contract>()
                //合同编号模糊查询
                .like(StringUtils.isNotEmpty(contractDto.getContractNo()), Contract::getContractNo, contractDto.getContractNo())
                //客户姓名模糊查询
                .like(StringUtils.isNotEmpty(contractDto.getName()), Contract::getName, contractDto.getName())
                //手机号模糊查询
                .like(StringUtils.isNotEmpty(contractDto.getPhone()), Contract::getPhone, contractDto.getPhone())
                //购买学科为精准查询
                .eq(contractDto.getSubject() != null, Contract::getSubject, contractDto.getSubject())
                //购买课程为精准查询
                .eq(contractDto.getCourseId() != null, Contract::getCourseId, contractDto.getCourseId());
        //创建时间用Map接收，需要取出来判断是否为空
        Object beginCreateTime = contractDto.getParams().get(BasePageResult.BEGIN_CREATE_TIME);
        Object endCreateTime = contractDto.getParams().get(BasePageResult.END_CREATE_TIME);
        //判断，不为空则加入查询条件
        if (ObjectUtils.isNotEmpty(beginCreateTime) && ObjectUtils.isNotEmpty(endCreateTime)){
            wrapper.between(Contract::getCreateTime, beginCreateTime, endCreateTime);
        }
        Page<Contract> page = super.page(contractPage, wrapper);
        return new BasePageResult(page.getRecords(), (int) page.getTotal());
    }

    /**
     * 获取合同详细信息
     * @param id
     * @return
     */
    @Override
    public Contract getContractInfoById(String id) {
        //获得合同信息
        Contract contract = contractMapper.selectById(id);
        //获得活动信息（折扣类型）
        String discountType = contract.getDiscountType();
        Integer activityId = contract.getActivityId();
        //获得课程价格
        Course course = courseMapper.selectById(contract.getCourseId());
        Double price  = course.getPrice().doubleValue();
        contract.setCoursePrice(price);
        //判断是否有优惠，需要计算购买金额
        if (DISCOUNT_TYPE_DISCOUNT.equals(discountType)){
            //优惠类型为打折,从活动表中获取折扣
            contract = getDiscountOrder(activityId, contract);
            return contract;
        }else if (DISCOUNT_TYPE_VOUCHERS.equals(discountType)){
            Activity activity = activityMapper.selectById(activityId);
            //设置活动信息（活动名称）
            contract.setDiscountType(activity.getName());
            //设置状态
            //todo 不知道是那个状态，先设成了活动的状态
            contract.setStatus(activity.getStatus().toString());
            //优惠类型为代金券,从活动表中获取代金券金额
            Integer vouchers = activity.getVouchers();
            //价格 - 代金券金额
            contract.setOrder(contract.getCoursePrice() - vouchers);
            return contract;
        }
        //没有折扣，原价购买
        contract.setOrder(contract.getCoursePrice());
        return contract;
    }

    /**
     * 商机转合同
     * @param dto
     * @param id
     */
    @Override
    public void change(ContractChangeDto dto, Integer id) {
        Business business = businessMapper.selectById(id);
        Contract contract = new Contract();
        BeanUtils.copyProperties(business,contract);
        //判断是否有活动信息
        if (ObjectUtils.isEmpty(business.getCourseId())){
          return;
        }
        //设置信息
        contract.setContractNo(dto.getContractNo());
        //设置手机号
        contract.setPhone(dto.getPhone());
        //设置id
        String contractID = UUID.randomUUID().toString().substring(0,8);
        contract.setId(contractID);
        //网址
        Integer userId = BaseContext.getCurrent().getUserId();
        Object url = redisTemplate.opsForValue().get(userId.toString());
        contract.setFileName(url.toString());
        //设置部门id
        String owner = business.getOwner();
        User user = userMapper.selectOne(Wrappers.<User>lambdaQuery().eq(User::getUserName,owner));
        contract.setDeptId(user.getDeptId());
        //判断是否需要打折
        if (ObjectUtils.isNotEmpty(contract.getActivityId())){
            //设置打折的金额
            Contract salary = getDiscountOrder(contract.getActivityId(), contract);
            //设置打折类型
            Activity activity = activityMapper.selectById(business.getActivityId());
            contract.setDiscountType(activity.getDiscount().toString());
        }
       //设置课程价格
        Course course = courseMapper.selectById(business.getCourseId());
        Integer price = course.getPrice();
        contract.setCoursePrice((double)price);
        //插入合同表
        contractMapper.insert(contract);
        //同时设置商机信息
        business.setStatus(0);
        businessMapper.updateById(business);
    }

    /**
     * 获取打折后的金额
     * @param activityId
     * @param contract
     * @return
     */
    private Contract getDiscountOrder(Integer activityId,Contract contract) {
        //获取活动信息
        Activity activity = activityMapper.selectById(activityId);
        //设置活动信息（活动名称）
        contract.setDiscountType(activity.getChannel().toString());
        //设置状态
        //todo 不知道是那个状态，先设成了活动的状态
        contract.setStatus(activity.getStatus().toString());
        //获得折扣
        Double discount = activity.getDiscount();
        //order = 价格 * 折扣
        //转为BigDecimal避免精度丢失
        BigDecimal dividend = new BigDecimal(discount.toString());
        BigDecimal divisor = new BigDecimal(DIVISOR);
        BigDecimal realDiscount = dividend.divide(divisor, RETENTION_NUMBER, RoundingMode.HALF_DOWN);
        // 获取课程价格并转换为 BigDecimal
        BigDecimal price = new BigDecimal(String.valueOf(contract.getCoursePrice()));
        contract.setOrder(price.multiply(realDiscount).doubleValue());
        return contract;
    }
}
